package com.martinzhuang.how_old;

import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.media.Image;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.facepp.error.FaceppParseException;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;


public class MainActivity extends ActionBarActivity implements View.OnClickListener {

    private static final int PICK_CODE = 0x11;//use to get photo
    private static final int CAM_OK = 0x12;
    private static final int MSG_SUCCESS = 0x111;//successfully get result
    private static final int MSG_ERROR = 0x112;//failed to get result

    private CustomProgressDialog customProgressDialog;
    private ImageView img_photo;
    private TextView tv_tip, tv_age_and_gender;
    private Button btn_detect, btn_get_image;
    private String mCurrentPhotoStr;
    private Bitmap mPhotoImage;
    private Paint mPaint;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        initEvent();

        mPaint = new Paint();
    }

    private void initView() {
        img_photo = (ImageView) findViewById(R.id.img_photo);
        tv_tip = (TextView) findViewById(R.id.tv_tip);
        btn_detect = (Button) findViewById(R.id.btn_detect);
        btn_get_image = (Button) findViewById(R.id.btn_get_image);
    }

    private void initEvent() {
        btn_detect.setOnClickListener(this);
        btn_get_image.setOnClickListener(this);
    }

    //handle detect message
    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {
                case MSG_SUCCESS:
                    stopProgressDialog();
                    //get json object
                    JSONObject jsonObject = (JSONObject) msg.obj;

                    //redraw face area the bitmap
                    prepareResultBitmap(jsonObject);

                    //set bitmap to image view
                    img_photo.setImageBitmap(mPhotoImage);
                    break;

                case MSG_ERROR:
                    stopProgressDialog();
                    //get error message
                    String errorMsg = (String) msg.obj;

                    //set text
                    if (TextUtils.isEmpty(errorMsg)) {
                        tv_tip.setText("Error");
                    } else {
                        tv_tip.setText(errorMsg);
                    }
                    break;
            }

            super.handleMessage(msg);
        }

    };

    //draw face box and age and gender
    private void prepareResultBitmap(JSONObject jsonObject) {

        Bitmap bitmap = Bitmap.createBitmap(mPhotoImage.getWidth(), mPhotoImage.getHeight(), mPhotoImage.getConfig());
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(mPhotoImage, 0, 0, null);

        try {
            //get all face object
            JSONArray faces = jsonObject.getJSONArray("face");
            //get face count
            int faceCount = faces.length();
            tv_tip.setText("find " + faceCount);

            for (int i = 0; i < faceCount; i++) {
                JSONObject face = faces.getJSONObject(i);
                JSONObject posObj = face.getJSONObject("position");

                //get face center coordinate
                float x = (float) posObj.getJSONObject("center").getDouble("x");
                float y = (float) posObj.getJSONObject("center").getDouble("y");

                //get face size
                float w = (float) posObj.getDouble("width");
                float h = (float) posObj.getDouble("height");

                //chage data to bitmap size
                x = x / 100 * bitmap.getWidth();
                y = y / 100 * bitmap.getHeight();
                w = w / 100 * bitmap.getWidth();
                h = h / 100 * bitmap.getHeight();

                mPaint.setColor(0xffffffff);
                mPaint.setStrokeWidth(3);

                //draw lines
                canvas.drawLine(x - w / 2, y + h / 2, x + w / 2, y + h / 2, mPaint);
                canvas.drawLine(x - w / 2, y + h / 2, x - w / 2, y - h / 2, mPaint);
                canvas.drawLine(x - w / 2, y - h / 2, x + w / 2, y - h / 2, mPaint);
                canvas.drawLine(x + w / 2, y + h / 2, x + w / 2, y - h / 2, mPaint);

                //get gender and age
                int age = face.getJSONObject("attribute").getJSONObject("age").getInt("value");
                String gender = face.getJSONObject("attribute").getJSONObject("gender").getString("value");

                //a bitmap that contain age and gender
                Bitmap ageBitmap = buildAgeBitmap(age, gender.equals("Male"));

                //size changed, make a ratio
                int ageWidth = ageBitmap.getWidth();
                int ageHeight = ageBitmap.getHeight();

                if (bitmap.getWidth() < img_photo.getWidth() && bitmap.getHeight() < img_photo.getHeight()) {
                    float ratio = Math.max(bitmap.getWidth() * 1.0f / img_photo.getWidth(), bitmap.getHeight() * 1.0f / img_photo.getHeight());
                    ageBitmap = Bitmap.createScaledBitmap(ageBitmap, (int) (ageWidth * ratio), (int) (ageHeight * ratio), false);
                }

                canvas.drawBitmap(ageBitmap, x - ageWidth / 2, y - h / 2 - ageHeight, null);

                mPhotoImage = bitmap;

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    //draw age and gender
    private Bitmap buildAgeBitmap(int age, boolean isMale) {
        tv_age_and_gender = (TextView) findViewById(R.id.tv_age_and_gender);
        tv_age_and_gender.setText(age + "");

        if (isMale) {
            tv_age_and_gender.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.male), null, null, null);
        } else {
            tv_age_and_gender.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.female), null, null, null);
        }

        tv_age_and_gender.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(tv_age_and_gender.getDrawingCache());
        tv_age_and_gender.destroyDrawingCache();

        return bitmap;
    }

    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.btn_detect:
                startProgressDialog();

                if (mCurrentPhotoStr != null && !mCurrentPhotoStr.trim().equals("")) {
                    resizePhoto();
                } else {
                    mPhotoImage = BitmapFactory.decodeResource(getResources(), R.drawable.t4);
                }

                FaceppDetect.detect(mPhotoImage, new FaceppDetect.CallBack() {
                    @Override
                    public void success(JSONObject result) {
                        //create a message
                        Message message = Message.obtain();

                        //set message info
                        message.what = MSG_SUCCESS;
                        message.obj = result;

                        //send message
                        mHandler.sendMessage(message);
                    }

                    @Override
                    public void error(FaceppParseException exception) {
                        //make a message
                        Message message = Message.obtain();

                        //set message info
                        message.what = MSG_ERROR;
                        message.obj = exception.getErrorMessage();

                        //send message
                        mHandler.sendMessage(message);
                    }
                });

                break;

            case R.id.btn_get_image:
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_PICK);
                intent.setType("image/*");
                startActivityForResult(intent, PICK_CODE);
                break;

            case R.id.img_photo:
                Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
                startActivityForResult(cameraIntent, CAM_OK);
                break;

            default:
                break;
        }

    }

    //set image view
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == PICK_CODE) {
            if (data != null) {
                //get uri of picture
                Uri uri = data.getData();
                //use uri to query
                Cursor cursor = getContentResolver().query(uri, null, null, null, null);
                cursor.moveToFirst();
                //get picture id that return by given column name
                int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                //get the picture path
                mCurrentPhotoStr = cursor.getString(idx);

                System.out.println(mCurrentPhotoStr);

                cursor.close();

                resizePhoto();

                img_photo.setImageBitmap(mPhotoImage);
                tv_tip.setText("Click Detect ==>");
            }
        } else if (requestCode == CAM_OK) {
            String sdStatus = Environment.getExternalStorageState();
            if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
                return;
            }
            Bundle bundle = data.getExtras();
            mPhotoImage = (Bitmap) bundle.get("data");
//            Bitmap bitmap = (Bitmap) bundle.get("data");//获取相机返回的数据，并转换为Bitmap图片格式
            FileOutputStream fileOutputStream = null;
//            File file = new File("/sdcard/");
//            file.mkdirs();// 创建文件夹，名称为myimage
//            //照片的命名，目标文件夹下，以当前时间数字串为名称，即可确保每张照片名称不相同。
//            String str = null;
//            Date date = null;
//            SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");//获取当前时间，进一步转化为字符串
//            date = new Date();
//            str = format.format(date);
            String fileName = "/sdcard/image.jpg";
            try {
                fileOutputStream = new FileOutputStream(fileName);
                mPhotoImage.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);//把数据写入文件
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } finally {
                try {
                    fileOutputStream.flush();
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (data != null) {
                    Bitmap cameraBitmap = (Bitmap) data.getExtras().get("data");
                    System.out.println(fileName);
                    mCurrentPhotoStr = Environment.getExternalStorageDirectory() + "/image.jpg";
                    img_photo.setImageBitmap(cameraBitmap);
                    tv_tip.setText("Click Detect ==>");
                }
            }
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    private void resizePhoto() {
        //use default optins to decode photo file
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(mCurrentPhotoStr, options);

        //set ratio to resize photo
        double ratio = Math.max(options.outWidth * 1.0d / 1024f, options.outHeight * 1.0d / 1024f);
        options.inSampleSize = (int) Math.ceil(ratio);
        options.inJustDecodeBounds = false;

        //photo size can't bigger than 3M
        mPhotoImage = BitmapFactory.decodeFile(mCurrentPhotoStr, options);
    }

    private void startProgressDialog() {
        if (customProgressDialog == null) {
            customProgressDialog = CustomProgressDialog.createDialog(this);
            customProgressDialog.setMessage("Scanning...");
        }

        customProgressDialog.show();
    }

    private void stopProgressDialog() {
        if (customProgressDialog != null) {
            customProgressDialog.dismiss();
            customProgressDialog = null;
        }
    }

}
